home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / gawk 2.11.1r3 / Sources / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-08  |  31.0 KB  |  1,180 lines  |  [TEXT/MPS ]

  1. /*
  2.  * eval.c - gawk parse tree interpreter 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* 01Jun91    Matthias Neeracher    <neeri@iis.ethz.ch>    MPW port */
  27.  
  28. #include "awk.h"
  29.  
  30. extern void do_print();
  31. extern void do_printf();
  32. extern NODE *do_match();
  33. extern NODE *do_sub();
  34. extern NODE *do_getline();
  35. extern NODE *concat_exp();
  36. extern int in_array();
  37. extern void do_delete();
  38. #ifndef macintosh
  39. extern double pow();
  40. #else
  41. #include <math.h>
  42. #endif
  43.  
  44. static int eval_condition();
  45. static NODE *op_assign();
  46. static NODE *func_call();
  47. static NODE *match_op();
  48.  
  49. NODE *_t;        /* used as a temporary in macros */
  50. #ifdef MSDOS
  51. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  52. #endif
  53. NODE *ret_node;
  54.  
  55. /* More of that debugging stuff */
  56. #ifdef    DEBUG
  57. #define DBG_P(X) print_debug X
  58. #else
  59. #define DBG_P(X)
  60. #endif
  61.  
  62. /* Macros and variables to save and restore function and loop bindings */
  63. /*
  64.  * the val variable allows return/continue/break-out-of-context to be
  65.  * caught and diagnosed
  66.  */
  67. #define PUSH_BINDING(stack, x, val) (memcpy ((char *)(stack), (char *)(x), sizeof (jmp_buf)), val++)
  68. #define RESTORE_BINDING(stack, x, val) (memcpy ((char *)(x), (char *)(stack), sizeof (jmp_buf)), val--)
  69.  
  70. static jmp_buf loop_tag;    /* always the current binding */
  71. static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  72. static int func_tag_valid = 0;
  73. static jmp_buf func_tag;
  74. extern int exiting, exit_val;
  75.  
  76. /*
  77.  * This table is used by the regexp routines to do case independant
  78.  * matching. Basically, every ascii character maps to itself, except
  79.  * uppercase letters map to lower case ones. This table has 256
  80.  * entries, which may be overkill. Note also that if the system this
  81.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  82.  * defined to the linker, so gawk should not load.
  83.  *
  84.  * Do NOT make this array static, it is used in several spots, not
  85.  * just in this file.
  86.  */
  87. #if 'a' == 97    /* it's ascii */
  88. char casetable[] = {
  89. #ifndef macintosh
  90.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  91.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  92.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  93.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  94.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  95.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  96.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  97.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  98.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  99.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  100.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  101.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  102.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  103.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  104.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  105.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  106.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  107.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  108.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  109.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  110.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  111.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  112.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  113.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  114.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  115.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  116.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  117.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  118.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  119.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  120.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  121.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  122.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  123.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  124.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  125.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  126.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  127.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  128.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  129.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  130.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  131.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  132.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  133.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  134. #else
  135. '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', 
  136. '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', 
  137. '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', 
  138. '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', 
  139. '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', 
  140. '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', 
  141. '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', 
  142. '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', 
  143. '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', 
  144. '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', 
  145. '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', 
  146. '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', 
  147. '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', 
  148. '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', 
  149. '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', 
  150. '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', 
  151. '\212', '\214', '\215', '\216', '\226', '\232', '\237', '\207', 
  152. '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', 
  153. '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', 
  154. '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', 
  155. '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', 
  156. '\250', '\251', '\252', '\253', '\254', '\255', '\276', '\277', 
  157. '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', 
  158. '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', 
  159. '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', 
  160. '\310', '\311', '\312', '\210', '\213', '\233', '\317', '\317', 
  161. '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', 
  162. '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', 
  163. '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', 
  164. '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', 
  165. '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', 
  166. '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', 
  167. #endif
  168. };
  169. #else
  170. #include "You lose. You will need a translation table for your character set."
  171. #endif
  172.  
  173. /*
  174.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  175.  * statement 
  176.  */
  177. int
  178. interpret(tree)
  179. NODE *tree;
  180. {
  181.     volatile jmp_buf loop_tag_stack; /* shallow binding stack for loop_tag */
  182.     static jmp_buf rule_tag;/* tag the rule currently being run, for NEXT
  183.                  * and EXIT statements.  It is static because
  184.                  * there are no nested rules */
  185.     register NODE *t = NULL;/* temporary */
  186.     volatile NODE **lhs;    /* lhs == Left Hand Side for assigns, etc */
  187.     volatile struct search *l;    /* For array_for */
  188.     volatile NODE *stable_tree;
  189.  
  190.     if (tree == NULL)
  191.         return 1;
  192.     sourceline = tree->source_line;
  193.     source = tree->source_file;
  194.     switch (tree->type) {
  195.     case Node_rule_list:
  196.         for (t = tree; t != NULL; t = t->rnode) {
  197.             tree = t->lnode;
  198.         /* FALL THROUGH */
  199.     case Node_rule_node:
  200.             sourceline = tree->source_line;
  201.             source = tree->source_file;
  202.             switch (setjmp(rule_tag)) {
  203.             case 0:    /* normal non-jump */
  204.                 /* test pattern, if any */
  205.                 if (tree->lnode == NULL 
  206.                     || eval_condition(tree->lnode)) {
  207.                     DBG_P(("Found a rule", tree->rnode));
  208.                     if (tree->rnode == NULL) {
  209.                         /*
  210.                          * special case: pattern with
  211.                          * no action is equivalent to
  212.                          * an action of {print}
  213.                          */
  214.                         NODE printnode;
  215.  
  216.                         printnode.type = Node_K_print;
  217.                         printnode.lnode = NULL;
  218.                         printnode.rnode = NULL;
  219.                         do_print(&printnode);
  220.                     } else if (tree->rnode->type == Node_illegal) {
  221.                         /*
  222.                          * An empty statement
  223.                          * (``{ }'') is different
  224.                          * from a missing statement.
  225.                          * A missing statement is
  226.                          * equal to ``{ print }'' as
  227.                          * above, but an empty
  228.                          * statement is as in C, do
  229.                          * nothing.
  230.                          */
  231.                     } else
  232.                         (void) interpret(tree->rnode);
  233.                 }
  234.                 break;
  235.             case TAG_CONTINUE:    /* NEXT statement */
  236.                 return 1;
  237.             case TAG_BREAK:
  238.                 return 0;
  239.             default:
  240.                 cant_happen();
  241.             }
  242.             if (t == NULL)
  243.                 break;
  244.         }
  245.         break;
  246.  
  247.     case Node_statement_list:
  248.         for (t = tree; t != NULL; t = t->rnode) {
  249.             DBG_P(("Statements", t->lnode));
  250.             (void) interpret(t->lnode);
  251.         }
  252.         break;
  253.  
  254.     case Node_K_if:
  255.         DBG_P(("IF", tree->lnode));
  256.         if (eval_condition(tree->lnode)) {
  257.             DBG_P(("True", tree->rnode->lnode));
  258.             (void) interpret(tree->rnode->lnode);
  259.         } else {
  260.             DBG_P(("False", tree->rnode->rnode));
  261.             (void) interpret(tree->rnode->rnode);
  262.         }
  263.         break;
  264.  
  265.     case Node_K_while:
  266.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  267.  
  268.         DBG_P(("WHILE", tree->lnode));
  269.         stable_tree = tree;
  270.         while (eval_condition(stable_tree->lnode)) {
  271.             switch (setjmp(loop_tag)) {
  272.             case 0:    /* normal non-jump */
  273.                 DBG_P(("DO", stable_tree->rnode));
  274.                 (void) interpret(stable_tree->rnode);
  275.                 break;
  276.             case TAG_CONTINUE:    /* continue statement */
  277.                 break;
  278.             case TAG_BREAK:    /* break statement */
  279.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  280.                 return 1;
  281.             default:
  282.                 cant_happen();
  283.             }
  284.         }
  285.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  286.         break;
  287.  
  288.     case Node_K_do:
  289.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  290.         stable_tree = tree;
  291.         do {
  292.             switch (setjmp(loop_tag)) {
  293.             case 0:    /* normal non-jump */
  294.                 DBG_P(("DO", stable_tree->rnode));
  295.                 (void) interpret(stable_tree->rnode);
  296.                 break;
  297.             case TAG_CONTINUE:    /* continue statement */
  298.                 break;
  299.             case TAG_BREAK:    /* break statement */
  300.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  301.                 return 1;
  302.             default:
  303.                 cant_happen();
  304.             }
  305.             DBG_P(("WHILE", stable_tree->lnode));
  306.         } while (eval_condition(stable_tree->lnode));
  307.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  308.         break;
  309.  
  310.     case Node_K_for:
  311.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  312.         DBG_P(("FOR", tree->forloop->init));
  313.         (void) interpret(tree->forloop->init);
  314.         DBG_P(("FOR.WHILE", tree->forloop->cond));
  315.         stable_tree = tree;
  316.         while (eval_condition(stable_tree->forloop->cond)) {
  317.             switch (setjmp(loop_tag)) {
  318.             case 0:    /* normal non-jump */
  319.                 DBG_P(("FOR.DO", stable_tree->lnode));
  320.                 (void) interpret(stable_tree->lnode);
  321.                 /* fall through */
  322.             case TAG_CONTINUE:    /* continue statement */
  323.                 DBG_P(("FOR.INCR", stable_tree->forloop->incr));
  324.                 (void) interpret(stable_tree->forloop->incr);
  325.                 break;
  326.             case TAG_BREAK:    /* break statement */
  327.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  328.                 return 1;
  329.             default:
  330.                 cant_happen();
  331.             }
  332.         }
  333.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  334.         break;
  335.  
  336.     case Node_K_arrayfor:
  337. #define hakvar forloop->init
  338. #define arrvar forloop->incr
  339.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  340.         DBG_P(("AFOR.VAR", tree->hakvar));
  341.         lhs = (volatile NODE **) get_lhs(tree->hakvar, 1);
  342.         t = tree->arrvar;
  343.         if (t->type == Node_param_list)
  344.             t = stack_ptr[t->param_cnt];
  345.         stable_tree = tree;
  346.         for (l = assoc_scan(t); l; l = assoc_next((struct search *)l)) {
  347.             deref = *((NODE **) lhs);
  348.             do_deref();
  349.             *lhs = dupnode(l->retval);
  350.             if (field_num == 0)
  351.                 set_record(fields_arr[0]->stptr,
  352.                     fields_arr[0]->stlen);
  353.             DBG_P(("AFOR.NEXTIS", *lhs));
  354.             switch (setjmp(loop_tag)) {
  355.             case 0:
  356.                 DBG_P(("AFOR.DO", stable_tree->lnode));
  357.                 (void) interpret(stable_tree->lnode);
  358.             case TAG_CONTINUE:
  359.                 break;
  360.  
  361.             case TAG_BREAK:
  362.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  363.                 field_num = -1;
  364.                 return 1;
  365.             default:
  366.                 cant_happen();
  367.             }
  368.         }
  369.         field_num = -1;
  370.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  371.         break;
  372.  
  373.     case Node_K_break:
  374.         DBG_P(("BREAK", NULL));
  375.         if (loop_tag_valid == 0)
  376.             fatal("unexpected break");
  377.         longjmp(loop_tag, TAG_BREAK);
  378.         break;
  379.  
  380.     case Node_K_continue:
  381.         DBG_P(("CONTINUE", NULL));
  382.         if (loop_tag_valid == 0)
  383.             fatal("unexpected continue");
  384.         longjmp(loop_tag, TAG_CONTINUE);
  385.         break;
  386.  
  387.     case Node_K_print:
  388.         DBG_P(("PRINT", tree));
  389.         do_print(tree);
  390.         break;
  391.  
  392.     case Node_K_printf:
  393.         DBG_P(("PRINTF", tree));
  394.         do_printf(tree);
  395.         break;
  396.  
  397.     case Node_K_next:
  398.         DBG_P(("NEXT", NULL));
  399.         longjmp(rule_tag, TAG_CONTINUE);
  400.         break;
  401.  
  402.     case Node_K_exit:
  403.         /*
  404.          * In A,K,&W, p. 49, it says that an exit statement "...
  405.          * causes the program to behave as if the end of input had
  406.          * occurred; no more input is read, and the END actions, if
  407.          * any are executed." This implies that the rest of the rules
  408.          * are not done. So we immediately break out of the main loop.
  409.          */
  410.         DBG_P(("EXIT", NULL));
  411.         exiting = 1;
  412.         if (tree) {
  413.             t = tree_eval(tree->lnode);
  414.             exit_val = (int) force_number(t);
  415.         }
  416.         free_temp(t);
  417.         longjmp(rule_tag, TAG_BREAK);
  418.         break;
  419.  
  420.     case Node_K_return:
  421.         DBG_P(("RETURN", NULL));
  422.         t = tree_eval(tree->lnode);
  423.         ret_node = dupnode(t);
  424.         free_temp(t);
  425.         longjmp(func_tag, TAG_RETURN);
  426.         break;
  427.  
  428.     default:
  429.         /*
  430.          * Appears to be an expression statement.  Throw away the
  431.          * value. 
  432.          */
  433.         DBG_P(("E", NULL));
  434.         t = tree_eval(tree);
  435.         free_temp(t);
  436.         break;
  437.     }
  438.     return 1;
  439. }
  440.  
  441. /* evaluate a subtree, allocating strings on a temporary stack. */
  442.  
  443. NODE *
  444. r_tree_eval(tree)
  445. NODE *tree;
  446. {
  447.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  448.     register NODE **lhs;
  449.     int di;
  450.     AWKNUM x, x2;
  451.     long lx;
  452.     extern NODE **fields_arr;
  453.  
  454.     source = tree->source_file;
  455.     sourceline = tree->source_line;
  456.     switch (tree->type) {
  457.     case Node_and:
  458.         DBG_P(("AND", tree));
  459.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  460.                         && eval_condition(tree->rnode)));
  461.  
  462.     case Node_or:
  463.         DBG_P(("OR", tree));
  464.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  465.                         || eval_condition(tree->rnode)));
  466.  
  467.     case Node_not:
  468.         DBG_P(("NOT", tree));
  469.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  470.  
  471.         /* Builtins */
  472.     case Node_builtin:
  473.         DBG_P(("builtin", tree));
  474.         return ((*tree->proc) (tree->subnode));
  475.  
  476.     case Node_K_getline:
  477.         DBG_P(("GETLINE", tree));
  478.         return (do_getline(tree));
  479.  
  480.     case Node_in_array:
  481.         DBG_P(("IN_ARRAY", tree));
  482.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  483.  
  484.     case Node_func_call:
  485.         DBG_P(("func_call", tree));
  486.         return func_call(tree->rnode, tree->lnode);
  487.  
  488.     case Node_K_delete:
  489.         DBG_P(("DELETE", tree));
  490.         do_delete(tree->lnode, tree->rnode);
  491.         return Nnull_string;
  492.  
  493.         /* unary operations */
  494.  
  495.     case Node_var:
  496.     case Node_var_array:
  497.     case Node_param_list:
  498.     case Node_subscript:
  499.     case Node_field_spec:
  500.         DBG_P(("var_type ref", tree));
  501.         lhs = get_lhs(tree, 0);
  502.         field_num = -1;
  503.         deref = 0;
  504.         return *lhs;
  505.  
  506.     case Node_unary_minus:
  507.         DBG_P(("UMINUS", tree));
  508.         t1 = tree_eval(tree->subnode);
  509.         x = -force_number(t1);
  510.         free_temp(t1);
  511.         return tmp_number(x);
  512.  
  513.     case Node_cond_exp:
  514.         DBG_P(("?:", tree));
  515.         if (eval_condition(tree->lnode)) {
  516.             DBG_P(("True", tree->rnode->lnode));
  517.             return tree_eval(tree->rnode->lnode);
  518.         }
  519.         DBG_P(("False", tree->rnode->rnode));
  520.         return tree_eval(tree->rnode->rnode);
  521.  
  522.     case Node_match:
  523.     case Node_nomatch:
  524.     case Node_regex:
  525.         DBG_P(("[no]match_op", tree));
  526.         return match_op(tree);
  527.  
  528.     case Node_func:
  529.         fatal("function `%s' called with space between name and (,\n%s",
  530.             tree->lnode->param,
  531.             "or used in other expression context");
  532.  
  533.     /* assignments */
  534.     case Node_assign:
  535.         DBG_P(("ASSIGN", tree));
  536.         r = tree_eval(tree->rnode);
  537.         lhs = get_lhs(tree->lnode, 1);
  538.         *lhs = dupnode(r);
  539.         free_temp(r);
  540.         do_deref();
  541.         if (field_num == 0)
  542.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  543.         field_num = -1;
  544.         return *lhs;
  545.  
  546.     /* other assignment types are easier because they are numeric */
  547.     case Node_preincrement:
  548.     case Node_predecrement:
  549.     case Node_postincrement:
  550.     case Node_postdecrement:
  551.     case Node_assign_exp:
  552.     case Node_assign_times:
  553.     case Node_assign_quotient:
  554.     case Node_assign_mod:
  555.     case Node_assign_plus:
  556.     case Node_assign_minus:
  557.         return op_assign(tree);
  558.     default:
  559.         break;    /* handled below */
  560.     }
  561.  
  562.     /* evaluate subtrees in order to do binary operation, then keep going */
  563.     t1 = tree_eval(tree->lnode);
  564.     t2 = tree_eval(tree->rnode);
  565.  
  566.     switch (tree->type) {
  567.     case Node_concat:
  568.         DBG_P(("CONCAT", tree));
  569.         t1 = force_string(t1);
  570.         t2 = force_string(t2);
  571.  
  572.         r = newnode(Node_val);
  573.         r->flags |= (STR|TEMP);
  574.         r->stlen = t1->stlen + t2->stlen;
  575.         r->stref = 1;
  576.         emalloc(r->stptr, char *, r->stlen + 1, "tree_eval");
  577.         memcpy(r->stptr, t1->stptr, t1->stlen);
  578.         memcpy(r->stptr + t1->stlen, t2->stptr, t2->stlen + 1);
  579.         free_temp(t1);
  580.         free_temp(t2);
  581.         return r;
  582.  
  583.     case Node_geq:
  584.     case Node_leq:
  585.     case Node_greater:
  586.     case Node_less:
  587.     case Node_notequal:
  588.     case Node_equal:
  589.         di = cmp_nodes(t1, t2);
  590.         free_temp(t1);
  591.         free_temp(t2);
  592.         switch (tree->type) {
  593.         case Node_equal:
  594.             DBG_P(("EQUAL", tree));
  595.             return tmp_number((AWKNUM) (di == 0));
  596.         case Node_notequal:
  597.             DBG_P(("NOT_EQUAL", tree));
  598.             return tmp_number((AWKNUM) (di != 0));
  599.         case Node_less:
  600.             DBG_P(("LESS_THAN", tree));
  601.             return tmp_number((AWKNUM) (di < 0));
  602.         case Node_greater:
  603.             DBG_P(("GREATER_THAN", tree));
  604.             return tmp_number((AWKNUM) (di > 0));
  605.         case Node_leq:
  606.             DBG_P(("LESS_THAN_EQUAL", tree));
  607.             return tmp_number((AWKNUM) (di <= 0));
  608.         case Node_geq:
  609.             DBG_P(("GREATER_THAN_EQUAL", tree));
  610.             return tmp_number((AWKNUM) (di >= 0));
  611.         default:
  612.             cant_happen();
  613.         }
  614.         break;
  615.     default:
  616.         break;    /* handled below */
  617.     }
  618.  
  619.     (void) force_number(t1);
  620.     (void) force_number(t2);
  621.  
  622.     switch (tree->type) {
  623.     case Node_exp:
  624.         DBG_P(("EXPONENT", tree));
  625.         if ((lx = t2->numbr) == t2->numbr) {    /* integer exponent */
  626.             if (lx == 0)
  627.                 x = 1;
  628.             else if (lx == 1)
  629.                 x = t1->numbr;
  630.             else {
  631.                 /* doing it this way should be more precise */
  632.                 for (x = x2 = t1->numbr; --lx; )
  633.                     x *= x2;
  634.             }
  635.         } else
  636.             x = pow((double) t1->numbr, (double) t2->numbr);
  637.         free_temp(t1);
  638.         free_temp(t2);
  639.         return tmp_number(x);
  640.  
  641.     case Node_times:
  642.         DBG_P(("MULT", tree));
  643.         x = t1->numbr * t2->numbr;
  644.         free_temp(t1);
  645.         free_temp(t2);
  646.         return tmp_number(x);
  647.  
  648.     case Node_quotient:
  649.         DBG_P(("DIVIDE", tree));
  650.         x = t2->numbr;
  651.         free_temp(t2);
  652.         if (x == (AWKNUM) 0)
  653.             fatal("division by zero attempted");
  654.             /* NOTREACHED */
  655.         else {
  656.             x = t1->numbr / x;
  657.             free_temp(t1);
  658.             return tmp_number(x);
  659.         }
  660.  
  661.     case Node_mod:
  662.         DBG_P(("MODULUS", tree));
  663.         x = t2->numbr;
  664.         free_temp(t2);
  665.         if (x == (AWKNUM) 0)
  666.             fatal("division by zero attempted in mod");
  667.             /* NOTREACHED */
  668.         lx = t1->numbr / x;    /* assignment to long truncates */
  669.         x2 = lx * x;
  670.         x = t1->numbr - x2;
  671.         free_temp(t1);
  672.         return tmp_number(x);
  673.  
  674.     case Node_plus:
  675.         DBG_P(("PLUS", tree));
  676.         x = t1->numbr + t2->numbr;
  677.         free_temp(t1);
  678.         free_temp(t2);
  679.         return tmp_number(x);
  680.  
  681.     case Node_minus:
  682.         DBG_P(("MINUS", tree));
  683.         x = t1->numbr - t2->numbr;
  684.         free_temp(t1);
  685.         free_temp(t2);
  686.         return tmp_number(x);
  687.  
  688.     default:
  689.         fatal("illegal type (%d) in tree_eval", tree->type);
  690.     }
  691.     return 0;
  692. }
  693.  
  694. /*
  695.  * This makes numeric operations slightly more efficient. Just change the
  696.  * value of a numeric node, if possible 
  697.  */
  698. void
  699. assign_number(ptr, value)
  700. NODE **ptr;
  701. AWKNUM value;
  702. {
  703.     extern NODE *deref;
  704.     register NODE *n = *ptr;
  705.  
  706. #ifdef DEBUG
  707.     if (n->type != Node_val)
  708.         cant_happen();
  709. #endif
  710.     if (n == Nnull_string) {
  711.         *ptr = make_number(value);
  712.         deref = 0;
  713.         return;
  714.     }
  715.     if (n->stref > 1) {
  716.         *ptr = make_number(value);
  717.         return;
  718.     }
  719.     if ((n->flags & STR) && (n->flags & (MALLOC|TEMP)))
  720.         free(n->stptr);
  721.     n->numbr = value;
  722.     n->flags |= (NUM|NUMERIC);
  723.     n->flags &= ~STR;
  724.     n->stref = 0;
  725.     deref = 0;
  726. }
  727.  
  728.  
  729. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  730. static int
  731. eval_condition(tree)
  732. NODE *tree;
  733. {
  734.     register NODE *t1;
  735.     int ret;
  736.  
  737.     if (tree == NULL)    /* Null trees are the easiest kinds */
  738.         return 1;
  739.     if (tree->type == Node_line_range) {
  740.         /*
  741.          * Node_line_range is kind of like Node_match, EXCEPT: the
  742.          * lnode field (more properly, the condpair field) is a node
  743.          * of a Node_cond_pair; whether we evaluate the lnode of that
  744.          * node or the rnode depends on the triggered word.  More
  745.          * precisely:  if we are not yet triggered, we tree_eval the
  746.          * lnode; if that returns true, we set the triggered word. 
  747.          * If we are triggered (not ELSE IF, note), we tree_eval the
  748.          * rnode, clear triggered if it succeeds, and perform our
  749.          * action (regardless of success or failure).  We want to be
  750.          * able to begin and end on a single input record, so this
  751.          * isn't an ELSE IF, as noted above.
  752.          */
  753.         if (!tree->triggered)
  754.             if (!eval_condition(tree->condpair->lnode))
  755.                 return 0;
  756.             else
  757.                 tree->triggered = 1;
  758.         /* Else we are triggered */
  759.         if (eval_condition(tree->condpair->rnode))
  760.             tree->triggered = 0;
  761.         return 1;
  762.     }
  763.  
  764.     /*
  765.      * Could just be J.random expression. in which case, null and 0 are
  766.      * false, anything else is true 
  767.      */
  768.  
  769.     t1 = tree_eval(tree);
  770.     if (t1->flags & NUMERIC)
  771.         ret = t1->numbr != 0.0;
  772.     else
  773.         ret = t1->stlen != 0;
  774.     free_temp(t1);
  775.     return ret;
  776. }
  777.  
  778. int
  779. cmp_nodes(t1, t2)
  780. NODE *t1, *t2;
  781. {
  782.     AWKNUM d;
  783.     AWKNUM d1;
  784.     AWKNUM d2;
  785.     int ret;
  786.     int len1, len2;
  787.  
  788.     if (t1 == t2)
  789.         return 0;
  790.     d1 = force_number(t1);
  791.     d2 = force_number(t2);
  792.     if ((t1->flags & NUMERIC) && (t2->flags & NUMERIC)) {
  793.         d = d1 - d2;
  794.         if (d == 0.0)    /* from profiling, this is most common */
  795.             return 0;
  796.         if (d > 0.0)
  797.             return 1;
  798.         return -1;
  799.     }
  800.     t1 = force_string(t1);
  801.     t2 = force_string(t2);
  802.     len1 = t1->stlen;
  803.     len2 = t2->stlen;
  804.     if (len1 == 0) {
  805.         if (len2 == 0)
  806.             return 0;
  807.         else
  808.             return -1;
  809.     } else if (len2 == 0)
  810.         return 1;
  811.     ret = memcmp(t1->stptr, t2->stptr, len1 <= len2 ? len1 : len2);
  812.     if (ret == 0 && len1 != len2)
  813.         return len1 < len2 ? -1: 1;
  814.     return ret;
  815. }
  816.  
  817. static NODE *
  818. op_assign(tree)
  819. NODE *tree;
  820. {
  821.     AWKNUM rval, lval;
  822.     NODE **lhs;
  823.     AWKNUM t1, t2;
  824.     long ltemp;
  825.     NODE *tmp;
  826.  
  827.     lhs = get_lhs(tree->lnode, 1);
  828.     lval = force_number(*lhs);
  829.  
  830.     switch(tree->type) {
  831.     case Node_preincrement:
  832.     case Node_predecrement:
  833.         DBG_P(("+-X", tree));
  834.         assign_number(lhs,
  835.             lval + (tree->type == Node_preincrement ? 1.0 : -1.0));
  836.         do_deref();
  837.         if (field_num == 0)
  838.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  839.         field_num = -1;
  840.         return *lhs;
  841.  
  842.     case Node_postincrement:
  843.     case Node_postdecrement:
  844.         DBG_P(("X+-", tree));
  845.         assign_number(lhs,
  846.             lval + (tree->type == Node_postincrement ? 1.0 : -1.0));
  847.         do_deref();
  848.         if (field_num == 0)
  849.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  850.         field_num = -1;
  851.         return tmp_number(lval);
  852.     default:
  853.         break;    /* handled below */
  854.     }
  855.  
  856.     tmp = tree_eval(tree->rnode);
  857.     rval = force_number(tmp);
  858.     free_temp(tmp);
  859.     switch(tree->type) {
  860.     case Node_assign_exp:
  861.         DBG_P(("ASSIGN_exp", tree));
  862.         if ((ltemp = rval) == rval) {    /* integer exponent */
  863.             if (ltemp == 0)
  864.                 assign_number(lhs, (AWKNUM) 1);
  865.             else if (ltemp == 1)
  866.                 assign_number(lhs, lval);
  867.             else {
  868.                 /* doing it this way should be more precise */
  869.                 for (t1 = t2 = lval; --ltemp; )
  870.                     t1 *= t2;
  871.                 assign_number(lhs, t1);
  872.             }
  873.         } else
  874.             assign_number(lhs, (AWKNUM) pow((double) lval, (double) rval));
  875.         break;
  876.  
  877.     case Node_assign_times:
  878.         DBG_P(("ASSIGN_times", tree));
  879.         assign_number(lhs, lval * rval);
  880.         break;
  881.  
  882.     case Node_assign_quotient:
  883.         DBG_P(("ASSIGN_quotient", tree));
  884.         if (rval == (AWKNUM) 0)
  885.             fatal("division by zero attempted in /=");
  886.         assign_number(lhs, lval / rval);
  887.         break;
  888.  
  889.     case Node_assign_mod:
  890.         DBG_P(("ASSIGN_mod", tree));
  891.         if (rval == (AWKNUM) 0)
  892.             fatal("division by zero attempted in %=");
  893.         ltemp = lval / rval;    /* assignment to long truncates */
  894.         t1 = ltemp * rval;
  895.         t2 = lval - t1;
  896.         assign_number(lhs, t2);
  897.         break;
  898.  
  899.     case Node_assign_plus:
  900.         DBG_P(("ASSIGN_plus", tree));
  901.         assign_number(lhs, lval + rval);
  902.         break;
  903.  
  904.     case Node_assign_minus:
  905.         DBG_P(("ASSIGN_minus", tree));
  906.         assign_number(lhs, lval - rval);
  907.         break;
  908.     default:
  909.         cant_happen();
  910.     }
  911.     do_deref();
  912.     if (field_num == 0)
  913.         set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  914.     field_num = -1;
  915.     return *lhs;
  916. }
  917.  
  918. NODE **stack_ptr;
  919.  
  920. static NODE *
  921. func_call(name, arg_list)
  922. NODE *name;        /* name is a Node_val giving function name */
  923. NODE *arg_list;        /* Node_expression_list of calling args. */
  924. {
  925.     register NODE *arg, *argp, *r;
  926.     NODE *n, *f;
  927.     volatile jmp_buf func_tag_stack;
  928.     volatile jmp_buf loop_tag_stack;
  929.     volatile int save_loop_tag_valid = 0;
  930.     volatile NODE **save_stack, *save_ret_node;
  931.     NODE **local_stack, **sp;
  932.     int count;
  933.     extern NODE *ret_node;
  934.  
  935.     /*
  936.      * retrieve function definition node
  937.      */
  938.     f = lookup(variables, name->stptr);
  939.     if (!f || f->type != Node_func)
  940.         fatal("function `%s' not defined", name->stptr);
  941. #ifdef FUNC_TRACE
  942.     fprintf(stderr, "function %s called\n", name->stptr);
  943. #endif
  944.     count = f->lnode->param_cnt;
  945.     emalloc(local_stack, NODE **, count * sizeof(NODE *), "func_call");
  946.     sp = local_stack;
  947.  
  948.     /*
  949.      * for each calling arg. add NODE * on stack
  950.      */
  951.     for (argp = arg_list; count && argp != NULL; argp = argp->rnode) {
  952.         arg = argp->lnode;
  953.         r = newnode(Node_var);
  954.         /*
  955.          * call by reference for arrays; see below also
  956.          */
  957.         if (arg->type == Node_param_list)
  958.             arg = stack_ptr[arg->param_cnt];
  959.         if (arg->type == Node_var_array)
  960.             *r = *arg;
  961.         else {
  962.             n = tree_eval(arg);
  963.             r->lnode = dupnode(n);
  964.             r->rnode = (NODE *) NULL;
  965.             free_temp(n);
  966.           }
  967.         *sp++ = r;
  968.         count--;
  969.     }
  970.     if (argp != NULL)    /* left over calling args. */
  971.         warning(
  972.             "function `%s' called with more arguments than declared",
  973.             name->stptr);
  974.     /*
  975.      * add remaining params. on stack with null value
  976.      */
  977.     while (count-- > 0) {
  978.         r = newnode(Node_var);
  979.         r->lnode = Nnull_string;
  980.         r->rnode = (NODE *) NULL;
  981.         *sp++ = r;
  982.     }
  983.  
  984.     /*
  985.      * Execute function body, saving context, as a return statement
  986.      * will longjmp back here.
  987.      *
  988.      * Have to save and restore the loop_tag stuff so that a return
  989.      * inside a loop in a function body doesn't scrog any loops going
  990.      * on in the main program.  We save the necessary info in variables
  991.      * local to this function so that function nesting works OK.
  992.      * We also only bother to save the loop stuff if we're in a loop
  993.      * when the function is called.
  994.      */
  995.     if (loop_tag_valid) {
  996.         int junk = 0;
  997.  
  998.         save_loop_tag_valid = (volatile int) loop_tag_valid;
  999.         PUSH_BINDING(loop_tag_stack, loop_tag, junk);
  1000.         loop_tag_valid = 0;
  1001.     }
  1002.     save_stack = (volatile NODE **) stack_ptr;
  1003.     stack_ptr = local_stack;
  1004.     PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
  1005.     save_ret_node = (volatile NODE *) ret_node;
  1006.     ret_node = Nnull_string;    /* default return value */
  1007.     if (setjmp(func_tag) == 0)
  1008.         (void) interpret(f->rnode);
  1009.  
  1010.     r = ret_node;
  1011.     ret_node = (NODE *) save_ret_node;
  1012.     RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
  1013.     stack_ptr = (NODE **) save_stack;
  1014.  
  1015.     /*
  1016.      * here, we pop each parameter and check whether
  1017.      * it was an array.  If so, and if the arg. passed in was
  1018.      * a simple variable, then the value should be copied back.
  1019.      * This achieves "call-by-reference" for arrays.
  1020.      */
  1021.     sp = local_stack;
  1022.     count = f->lnode->param_cnt;
  1023.     for (argp = arg_list; count > 0 && argp != NULL; argp = argp->rnode) {
  1024.         arg = argp->lnode;
  1025.         n = *sp++;
  1026.         if (arg->type == Node_var && n->type == Node_var_array) {
  1027.             arg->var_array = n->var_array;
  1028.             arg->type = Node_var_array;
  1029.         }
  1030.         deref = n->lnode;
  1031.         do_deref();
  1032.         freenode(n);
  1033.         count--;
  1034.     }
  1035.     while (count-- > 0) {
  1036.         n = *sp++;
  1037.         deref = n->lnode;
  1038.         do_deref();
  1039.         freenode(n);
  1040.     }
  1041.     free((char *) local_stack);
  1042.  
  1043.     /* Restore the loop_tag stuff if necessary. */
  1044.     if (save_loop_tag_valid) {
  1045.         int junk = 0;
  1046.  
  1047.         loop_tag_valid = (int) save_loop_tag_valid;
  1048.         RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
  1049.     }
  1050.  
  1051.     if (!(r->flags & PERM))
  1052.         r->flags |= TEMP;
  1053.     return r;
  1054. }
  1055.  
  1056. /*
  1057.  * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
  1058.  * value of the var, or where to store the var's new value 
  1059.  */
  1060.  
  1061. NODE **
  1062. get_lhs(ptr, assign)
  1063. NODE *ptr;
  1064. int assign;        /* this is being called for the LHS of an assign. */
  1065. {
  1066.     register NODE **aptr;
  1067.     NODE *n;
  1068.  
  1069. #ifdef DEBUG
  1070.     if (ptr == NULL)
  1071.         cant_happen();
  1072. #endif
  1073.     deref = NULL;
  1074.     field_num = -1;
  1075.     switch (ptr->type) {
  1076.     case Node_var:
  1077.     case Node_var_array:
  1078.         if (ptr == NF_node && (int) NF_node->var_value->numbr == -1)
  1079.             (void) get_field(HUGE-1, assign); /* parse record */
  1080.         deref = ptr->var_value;
  1081. #ifdef DEBUG
  1082.         if (deref->type != Node_val)
  1083.             cant_happen();
  1084.         if (deref->flags == 0)
  1085.             cant_happen();
  1086. #endif
  1087.         return &(ptr->var_value);
  1088.  
  1089.     case Node_param_list:
  1090.         n = stack_ptr[ptr->param_cnt];
  1091.         deref = n->var_value;
  1092. #ifdef DEBUG
  1093.         if (deref->type != Node_val)
  1094.             cant_happen();
  1095.         if (deref->flags == 0)
  1096.             cant_happen();
  1097. #endif
  1098.         return &(n->var_value);
  1099.  
  1100.     case Node_field_spec:
  1101.         n = tree_eval(ptr->lnode);
  1102.         field_num = (int) force_number(n);
  1103.         free_temp(n);
  1104.         if (field_num < 0)
  1105.             fatal("attempt to access field %d", field_num);
  1106.         aptr = get_field(field_num, assign);
  1107.         deref = *aptr;
  1108.         return aptr;
  1109.  
  1110.     case Node_subscript:
  1111.         n = ptr->lnode;
  1112.         if (n->type == Node_param_list)
  1113.             n = stack_ptr[n->param_cnt];
  1114.         aptr = assoc_lookup(n, concat_exp(ptr->rnode));
  1115.         deref = *aptr;
  1116. #ifdef DEBUG
  1117.         if (deref->type != Node_val)
  1118.             cant_happen();
  1119.         if (deref->flags == 0)
  1120.             cant_happen();
  1121. #endif
  1122.         return aptr;
  1123.     case Node_func:
  1124.         fatal ("`%s' is a function, assignment is not allowed",
  1125.             ptr->lnode->param);
  1126.     default:
  1127.         cant_happen();
  1128.     }
  1129.     return 0;
  1130. }
  1131.  
  1132. static NODE *
  1133. match_op(tree)
  1134. NODE *tree;
  1135. {
  1136.     NODE *t1;
  1137.     struct re_pattern_buffer *rp;
  1138.     int i;
  1139.     int match = 1;
  1140.  
  1141.     if (tree->type == Node_nomatch)
  1142.         match = 0;
  1143.     if (tree->type == Node_regex)
  1144.         t1 = WHOLELINE;
  1145.     else {
  1146.         if (tree->lnode)
  1147.             t1 = force_string(tree_eval(tree->lnode));
  1148.         else
  1149.             t1 = WHOLELINE;
  1150.         tree = tree->rnode;
  1151.     }
  1152.     if (tree->type == Node_regex) {
  1153.         rp = tree->rereg;
  1154.         if (!strict && ((IGNORECASE_node->var_value->numbr != 0)
  1155.             ^ (tree->re_case != 0))) {
  1156.             /* recompile since case sensitivity differs */
  1157.             rp = tree->rereg =
  1158.                 mk_re_parse(tree->re_text,
  1159.                 (IGNORECASE_node->var_value->numbr != 0));
  1160.             tree->re_case =
  1161.                 (IGNORECASE_node->var_value->numbr != 0);
  1162.         }
  1163.     } else {
  1164.         rp = make_regexp(force_string(tree_eval(tree)),
  1165.             (IGNORECASE_node->var_value->numbr != 0));
  1166.         if (rp == NULL)
  1167.             cant_happen();
  1168.     }
  1169.     i = re_search(rp, t1->stptr, t1->stlen, 0, t1->stlen,
  1170.         (struct re_registers *) NULL);
  1171.     i = (i == -1) ^ (match == 1);
  1172.     free_temp(t1);
  1173.     if (tree->type != Node_regex) {
  1174.         free(rp->buffer);
  1175.         free(rp->fastmap);
  1176.         free((char *) rp);
  1177.     }
  1178.     return tmp_number((AWKNUM) i);
  1179. }
  1180.